home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / Sample Code Update 01⁄96 / Fragment Tool / Sources / DialogStuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-20  |  22.1 KB  |  843 lines  |  [TEXT/MPCC]

  1. /*
  2.     File:        Dialogs.c
  3.  
  4.     Contains:    Handle application's dialogs
  5.  
  6.     Written by:    Chris White, Developer Technical Support
  7.     
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9.     
  10.     Change History (most recent first):
  11.     
  12.                   9/28/95    CW        First release
  13.  
  14. */
  15.  
  16.  
  17.  
  18.  
  19.  
  20. #ifndef __TYPES__
  21.     #include <Types.h>
  22. #endif
  23.  
  24. #ifndef __QUICKDRAW__
  25.     #include <Quickdraw.h>
  26. #endif
  27.  
  28. #ifndef __QDOFFSCREEN__
  29.     #include <QDOffscreen.h>
  30. #endif
  31.  
  32. #ifndef __DESK__
  33.     #include <Desk.h>
  34. #endif
  35.  
  36. #ifndef __LOWMEM__
  37.     #include <LowMem.h>
  38. #endif
  39.  
  40. #ifndef __TEXTUTILS__
  41.     #include <TextUtils.h>
  42. #endif
  43.  
  44. #ifndef __DIALOGS__
  45.     #include <Dialogs.h>
  46. #endif
  47.  
  48. #ifndef __STDDEF__
  49.     #include <stddef.h>
  50. #endif
  51.  
  52. #ifndef __CODEFRAGMENTS__
  53.     #include <CodeFragments.h>
  54. #endif
  55.  
  56. #ifndef __STANDARDFILE__
  57.     #include <StandardFile.h>
  58. #endif
  59.  
  60. #ifndef __FOLDERS__
  61.     #include <Folders.h>
  62. #endif
  63.  
  64.  
  65.  
  66.  
  67. #ifndef __FRAGMENTTOOL__
  68.     #include "FragmentTool.h"
  69. #endif
  70.  
  71. #ifndef __FRAGMENTSTUFF__
  72.     #include "FragmentStuff.h"
  73. #endif
  74.  
  75. #ifndef __DIALOGSTUFF__
  76.     #include "DialogStuff.h"
  77. #endif
  78.  
  79. #ifndef __STREAMS__
  80.     #include "Streams.h"
  81. #endif
  82.  
  83. #ifndef __UTILITIES__
  84.     #include "Utilities.h"
  85. #endif
  86.  
  87. #ifndef __PROTOTYPES__
  88.     #include "Prototypes.h"
  89. #endif
  90.  
  91.  
  92.  
  93.  
  94. static OSErr CreateContentList ( WindowRef theWindow, tContentsProcPtr contentsProc, void* refCon );
  95. static void AddContentsToList ( WindowRef theWindow );
  96. static int8 GetStageFromItem ( int16 theItem );
  97. static int16 GetItemFromStage ( int8 theStage );
  98. void GetNameFromDialog ( DialogRef theDialog, StringPtr theName );
  99.  
  100.  
  101.  
  102.  
  103.  
  104. //
  105. // Creates a simple dialog with a single list. A routine pointer is passed
  106. // as an argument which add the list contents.
  107. //
  108. OSErr CreateListDialog ( DialogRef* dialogRef, int16 dialogID, StringPtr dialogTitle,
  109.                             tContentsProcPtr contentsProc, void* refCon )
  110. {
  111.     int16            theType;
  112.     OSErr            theErr;
  113.     GrafPtr            savePort;
  114.     DialogRef        theDialog = nil;
  115.     ListRef            theList = nil;
  116.     Handle            theHandle;
  117.     Point            cellSize = {0, 0};
  118.     Cell            firstCell = {0, 0};
  119.     Rect            dataRect = {0, 0, 0, 1};
  120.     Rect            theRect;
  121.     
  122.     
  123.     
  124.     theDialog = GetNewDialog ( dialogID, nil, (WindowRef) -1L );
  125.     if ( theDialog == nil )
  126.         return kGenericError;
  127.     
  128.     // Creates the data structure assigned to the window's refCon field
  129.     theErr = CreateWindowInfo ( theDialog, sizeof ( tDialogInfo ) );
  130.     if ( theErr )
  131.     {
  132.         // Don't forget to free any storage we've used so far
  133.         DestroyDialog ( theDialog );
  134.         return theErr;
  135.     }
  136.     
  137.     GetPort ( &savePort );
  138.     SetPortWindowPort ( theDialog );
  139.     TextFont ( geneva );
  140.     TextFace ( normal );
  141.     TextSize ( 9 );
  142.     
  143.     SetWindowType ( theDialog, kListWindowType );
  144.     SetWTitle ( theDialog, dialogTitle );
  145.     
  146.     GetDialogItem ( theDialog, kListUserItem, &theType, &theHandle, &theRect );
  147.     SetDialogItem ( theDialog, kListUserItem, theType, (Handle) gOutlineUserItemUPP, &theRect );
  148.     
  149.     theRect.right -= 15;
  150.     theList = LNew ( &theRect, &dataRect, cellSize, 0, theDialog, 
  151.                         false, false, false, true );
  152.     if ( theList )
  153.     {
  154.         tDialogInfoPtr    theInfo;
  155.         
  156.         theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  157.         theInfo->listRef = theList;
  158.         (*theList)->selFlags = lOnlyOne;
  159.         
  160.         // Since the calling routine is always in the same architecture type as
  161.         // the callback routine, we don't need to worry about any Mixed Mode
  162.         // complications. We just treat it as a straight forward routine pointer.
  163.         
  164.         theErr = (*contentsProc) ( theList, refCon );
  165.         if ( theErr )
  166.         {
  167.             // Don't forget to free any storage we've used so far
  168.             DestroyDialog ( theDialog );
  169.             SetPort ( savePort );
  170.             return theErr;
  171.         }
  172.         
  173.         LSetSelect ( true, firstCell, theList );
  174.  
  175.         // Now the list has been fully prepared, turn the drawing mode on. This
  176.         // isn't srictly necessary since the window isn't supposed to visible.
  177.         LSetDrawingMode ( true, theList );
  178.     }
  179.     
  180.     SetPort ( savePort );
  181.     
  182.     SelectWindow ( theDialog );
  183.     ShowWindow ( theDialog );
  184.  
  185.     *dialogRef = theDialog;
  186.     
  187.     return noErr;
  188. }
  189.  
  190.  
  191.  
  192. //
  193. // Creates the dialog used for the GetInfo command. Displays information about
  194. // the code fragment. This is the stuff contained within the 'cfrg' resource
  195. //
  196. OSErr CreateInfoDialog ( DialogRef* dialogRef, StringPtr dialogTitle, WindowRef theWindow, int16 theIndex )
  197. {
  198.     OSErr            theErr;
  199.     GrafPtr            savePort = nil;
  200.     DialogRef        theDialog = nil;
  201.     TEHandle        textH;
  202.     tDialogInfoPtr    theInfo;
  203.     tStreamRef        theStream = nil;
  204.     tItemPtr        theItem;
  205.     FontInfo        theFontInfo;
  206.  
  207.     
  208.     theDialog = GetNewDialog ( 2002, nil, (WindowRef) -1L );
  209.     if ( theDialog == nil )
  210.         return kGenericError;
  211.     
  212.     theErr = CreateWindowInfo ( theDialog, sizeof ( tDialogInfo ) );
  213.     if ( theErr )
  214.         goto CleanupAndBail;
  215.     
  216.     GetPort ( &savePort );
  217.     SetPortWindowPort ( theDialog );
  218.     TextFont ( geneva );
  219.     TextFace ( normal );
  220.     TextSize ( 9 );
  221.     
  222.     // We're using a different font than the standard, so we need to
  223.     // change the fields in the textedit record. Otherwise, any text
  224.     // that is being edited will be display in the standard font.
  225.     GetFontInfo ( &theFontInfo );
  226.     textH = ((DialogPeek) theDialog)->textH;
  227.     (*textH)->txFont = geneva;
  228.     (*textH)->txFace = normal;
  229.     (*textH)->txSize = 9;
  230.     (*textH)->lineHeight = theFontInfo.ascent + theFontInfo.descent + theFontInfo.leading;
  231.     (*textH)->fontAscent = theFontInfo.ascent;
  232.     
  233.     SetWindowType ( theDialog, kGetInfoWindowType );
  234.     SetWTitle ( theDialog, dialogTitle );
  235.     
  236.     
  237.     // The window is needed to make the document dirty if the user makes
  238.     // a change. The item points to the information displayed in the dialog.
  239.     
  240.     theErr = NewStream ( &theStream, sizeof ( WindowRef ) + sizeof ( int16 ) );
  241.     if ( theErr ) goto CleanupAndBail;
  242.     
  243.     theErr = SetStreamData ( theStream, (Ptr) &theWindow, sizeof ( WindowRef ) );
  244.     if ( theErr ) goto CleanupAndBail;
  245.     
  246.     theErr = SetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  247.     if ( theErr ) goto CleanupAndBail;
  248.  
  249.     theErr = CompactStream ( theStream );
  250.     if ( theErr ) goto CleanupAndBail;
  251.     
  252.     theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  253.     theInfo->refCon = (int32) theStream;
  254.     
  255.     // Set up the dialog with the information from the selected item 
  256.     theItem = GetNthWindowItem ( theWindow, theIndex );
  257.     theErr = SetDialogValues ( theDialog, theItem );
  258.     if ( theErr ) goto CleanupAndBail;
  259.     
  260.     SetPort ( savePort );
  261.     
  262.     SelectWindow ( theDialog );
  263.     ShowWindow ( theDialog );
  264.     
  265.     *dialogRef = theDialog;
  266.     
  267.     return noErr;
  268.     
  269. CleanupAndBail:
  270.     // Don't forget to free any storage we've used so far. goto's are very useful
  271.     // for things like error recovery. That's how many of the exception stack
  272.     // implementations work in class frameworks.
  273.     
  274.     if ( theStream )
  275.         DisposeStream ( theStream );
  276.     if ( theDialog )
  277.         DestroyDialog ( theDialog );
  278.     if ( savePort )
  279.         SetPort ( savePort );
  280.         
  281.     return theErr;
  282. }
  283.  
  284.  
  285.  
  286. //
  287. // Our one-fits-all routine to free up everything
  288. // to do with a  dialog.
  289. //
  290. DialogRef DestroyDialog ( DialogRef theDialog )
  291. {
  292.     if ( theDialog )
  293.     {
  294.         tDialogInfoPtr    theInfo;
  295.         
  296.         theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  297.         if ( theInfo )
  298.         {
  299.             if ( theInfo->listRef )
  300.                 LDispose ( theInfo->listRef );
  301.             DisposePtr ( (Ptr) theInfo );
  302.         }
  303.         
  304.         DisposeDialog ( theDialog );
  305.     }
  306.     
  307.     // We'll return nil so the result can assigned to
  308.     // the dialog reference that was passed in.
  309.     return nil;
  310. }
  311.  
  312.  
  313.  
  314. //
  315. // This routine's pointer is passed into CreateListDialog
  316. // to add the contents to a newly created list.
  317. //
  318. OSErr AddFragmentExports ( ListRef theList, void* refCon )
  319. {
  320.     int                        i;
  321.     int32                    theCount;
  322.     OSErr                    theErr = noErr;
  323.     LoadFlags                theFlags = kLoadLib;
  324.     tItemPtr                theItem;
  325.     Ptr                        mainAddr, symAddr;
  326.     ConnectionID            theConnID;
  327.     SymClass                symClass;
  328.     tAddFragmentExportsRec*    theRec;
  329.     Str255                    symName;
  330.     static Str255            errName;
  331.     
  332.     
  333.     theRec = (tAddFragmentExportsRec*) refCon;
  334.     theItem = theRec->u.out.theItem;
  335.     if ( theItem == nil )
  336.         return kGenericError;
  337.     
  338.     
  339.     // Since 'errName' must be valid after the routine has
  340.     // gone out of scope, the variable is declaired static.
  341.     
  342.     
  343.     // The fragment may not exist in the document yet. If this is the
  344.     // case, we'll need to get the fragment from the temporary file. 
  345.     if ( theItem->bExistsInDocument )
  346.         theErr = GetDiskFragment ( theRec->u.out.theSpecPtr, theItem->codeOffset, theItem->codeLength,
  347.                                     theItem->name, theFlags, &theConnID, &mainAddr, errName );
  348.     else
  349.         theErr = GetDiskFragment ( GetTempSpecPtr ( theItem ), 0, 0, theItem->name, theFlags, &theConnID, &mainAddr, errName );
  350.     
  351.     if ( theErr )
  352.     {
  353.         theRec->bIn = true;
  354.         theRec->u.in.theErrorStr = errName;
  355.         return theErr;
  356.     }
  357.     
  358.     theErr = CountSymbols ( theConnID, &theCount );
  359.     if ( theErr ) goto CleanupAndBail;
  360.     
  361.     for ( i = 0; i < theCount; i++ )
  362.     {
  363.         theErr = GetIndSymbol ( theConnID, i, symName, &symAddr, &symClass );
  364.         if ( theErr ) goto CleanupAndBail;
  365.         
  366.         AddToList ( theList, symName );
  367.     }
  368.     
  369.     
  370. CleanupAndBail:
  371.     
  372.     CloseConnection ( &theConnID );
  373.     
  374.     return theErr;
  375. }
  376.  
  377.  
  378.  
  379. //
  380. // This routine's pointer is passed into CreateListDialog
  381. // to add the names of each document, except the front-most.
  382. //
  383. OSErr AddDocuments ( ListRef theList, void* refCon )
  384. {
  385.     int            theIndex = 0;
  386.     WindowRef    theWindow;
  387.     
  388.     
  389.     
  390.     // By structuring the routines this way, we can ensure that the index we
  391.     // retrive from the List Manager (as the selected item) can be passed into
  392.     // the GetIndexedDocumentWindow routine to get the correct window. This
  393.     // minimizes any logical dependencies between different routines. Most
  394.     // of the logic is contained within the GetIndexedDocumentWindow routine.
  395.     
  396.     while ( theWindow = GetIndexedDocumentWindow ( theIndex++ ) )
  397.     {
  398.         Str255    theText;
  399.         
  400.         GetWTitle ( theWindow, theText );
  401.         AddToList ( theList, theText );
  402.     }
  403.     
  404.     return noErr;
  405. }
  406.  
  407.  
  408.  
  409. // This routine is called to setup all the dialog items with the information
  410. // from a fragment. We pass in a pointer to its data structure.
  411. OSErr SetDialogValues ( DialogRef theDialog, tItemPtr theItem )
  412. {
  413.     int16    itemType;
  414.     int16    tmpNum;
  415.     Handle    theHandle;
  416.     Rect    theRect;
  417.     Str255    tmpString = "\p";
  418.     
  419.     // Name of the fragment
  420.     GetDialogItem ( theDialog, kNameEditText, &itemType, &theHandle, &theRect );
  421.     SetDialogItemText ( theHandle, theItem->name );
  422.     
  423.     // The fragment's arichtecture. For example, m68k
  424.     GetDialogItem ( theDialog, kArchitectureStaticText, &itemType, &theHandle, &theRect );
  425.     OSTypeToPStr ( theItem->archType, tmpString );
  426.     SetDialogItemText ( theHandle, tmpString );
  427.     
  428.     // The update level. We use a popup menu for this information
  429.     GetDialogItem ( theDialog, kUpdateLevelPopup, &itemType, &theHandle, &theRect );
  430.     SetControlValue ( (ControlHandle) theHandle, theItem->updateLevel + 1 );
  431.     
  432.     // Current Version
  433.     GetDialogItem ( theDialog, kCurrentMajorEditText, &itemType, &theHandle, &theRect );
  434.     NumToString ( (*(NumVersion*)&theItem->currVersion).majorRev, tmpString );
  435.     SetDialogItemText ( theHandle, tmpString );
  436.     
  437.     GetDialogItem ( theDialog, kCurrentMinorEditText, &itemType, &theHandle, &theRect );
  438.     NumToString ( (*(NumVersion*)&theItem->currVersion).minorAndBugRev & 0xF0, tmpString );
  439.     SetDialogItemText ( theHandle, tmpString );
  440.     
  441.     GetDialogItem ( theDialog, kCurrentBugRevEditText, &itemType, &theHandle, &theRect );
  442.     NumToString ( (*(NumVersion*)&theItem->currVersion).minorAndBugRev & 0x0F, tmpString );
  443.     SetDialogItemText ( theHandle, tmpString );
  444.     
  445.     GetDialogItem ( theDialog, kCurrentStagePopup, &itemType, &theHandle, &theRect );
  446.     tmpNum = GetItemFromStage ( (*(NumVersion*)&theItem->currVersion).stage );
  447.     SetControlValue ( (ControlHandle) theHandle, tmpNum );
  448.  
  449.     GetDialogItem ( theDialog, kCurrentNonRelEditText, &itemType, &theHandle, &theRect );
  450.     NumToString ( (*(NumVersion*)&theItem->currVersion).nonRelRev, tmpString );
  451.     SetDialogItemText ( theHandle, tmpString );
  452.     
  453.     // Old Version
  454.     GetDialogItem ( theDialog, kOldMajorEditText, &itemType, &theHandle, &theRect );
  455.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).majorRev, tmpString );
  456.     SetDialogItemText ( theHandle, tmpString );
  457.     
  458.     GetDialogItem ( theDialog, kOldMinorEditText, &itemType, &theHandle, &theRect );
  459.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev & 0xF0, tmpString );
  460.     SetDialogItemText ( theHandle, tmpString );
  461.     
  462.     GetDialogItem ( theDialog, kOldBugRevEditText, &itemType, &theHandle, &theRect );
  463.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev & 0x0F, tmpString );
  464.     SetDialogItemText ( theHandle, tmpString );
  465.     
  466.     GetDialogItem ( theDialog, kOldStagePopup, &itemType, &theHandle, &theRect );
  467.     tmpNum = GetItemFromStage ( (*(NumVersion*)&theItem->oldDefVersion).stage );
  468.     SetControlValue ( (ControlHandle) theHandle, tmpNum );
  469.     
  470.     GetDialogItem ( theDialog, kOldNonRelEditText, &itemType, &theHandle, &theRect );
  471.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).nonRelRev, tmpString );
  472.     SetDialogItemText ( theHandle, tmpString );
  473.     
  474.     // Stack size. Only relevant if this thing's an application
  475.     GetDialogItem ( theDialog, kStackSizeEditText, &itemType, &theHandle, &theRect );
  476.     NumToString ( theItem->appStackSize / 1024, tmpString );
  477.     SetDialogItemText ( theHandle, tmpString );
  478.     
  479.     // Resource ID of an alias record to look for fragments. We don't do much with this.
  480.     GetDialogItem ( theDialog, kSubFolderIDEditText, &itemType, &theHandle, &theRect );
  481.     NumToString ( theItem->appStackSize, tmpString );
  482.     SetDialogItemText ( theHandle, tmpString );
  483.     
  484.     // Usage. Is this an application, library, or what.
  485.     GetDialogItem ( theDialog, kUsagePopup, &itemType, &theHandle, &theRect );
  486.     SetControlValue ( (ControlHandle) theHandle, theItem->usage + 1 );
  487.     
  488.     // This is currently "hard-coded" in the dialog resource. We'll leave it alone.
  489.     GetDialogItem ( theDialog, kLocationStaticText, &itemType, &theHandle, &theRect );
  490.     // NumToString ( theItem->location, tmpString );
  491.     // SetDialogItemText ( theHandle, tmpString );
  492.     
  493.     // Offset to the fragment in the data fork.
  494.     if ( theItem->bExistsInDocument ) // Has it been saved? We don't know the offset otherwise
  495.     {
  496.         GetDialogItem ( theDialog, kOffsetStaticText, &itemType, &theHandle, &theRect );
  497.         NumToString ( theItem->codeOffset, tmpString );
  498.         SetDialogItemText ( theHandle, tmpString );
  499.     }
  500.     
  501.     // Length of the fragment in the data fork
  502.     GetDialogItem ( theDialog, kLengthStaticText, &itemType, &theHandle, &theRect );
  503.     NumToString ( theItem->codeLength, tmpString );
  504.     SetDialogItemText ( theHandle, tmpString );
  505.     
  506.     return noErr;
  507. }
  508.  
  509.  
  510.  
  511. //
  512. // The opposite of the above routine. This one gets the values from the dialog
  513. // fields and puts them in the fragment's data structure
  514. //
  515. OSErr GetDialogValues ( DialogRef theDialog, tItemPtr theItem )
  516. {
  517.     int16    itemType;
  518.     int32    tmpNum;
  519.     Handle    theHandle;
  520.     Rect    theRect;
  521.     Str255    tmpString = "\p";
  522.     
  523.  
  524.  
  525.     // Name of the fragment
  526.     GetDialogItem ( theDialog, kNameEditText, &itemType, &theHandle, &theRect );
  527.     GetDialogItemText ( theHandle, theItem->name );
  528.     
  529.     // The update level. We use a popup menu for this information
  530.     GetDialogItem ( theDialog, kUpdateLevelPopup, &itemType, &theHandle, &theRect );
  531.     theItem->updateLevel = GetControlValue ( (ControlHandle) theHandle ) - 1;
  532.     
  533.     // Current Version
  534.     GetDialogItem ( theDialog, kCurrentMajorEditText, &itemType, &theHandle, &theRect );
  535.     GetDialogItemText ( theHandle, tmpString );
  536.     StringToNum ( tmpString, &tmpNum );
  537.     (*(NumVersion*)&theItem->currVersion).majorRev = tmpNum;
  538.     
  539.     GetDialogItem ( theDialog, kCurrentMinorEditText, &itemType, &theHandle, &theRect );
  540.     GetDialogItemText ( theHandle, tmpString );
  541.     StringToNum ( tmpString, &tmpNum );
  542.     (*(NumVersion*)&theItem->currVersion).minorAndBugRev = tmpNum << 4;
  543.     
  544.     GetDialogItem ( theDialog, kCurrentBugRevEditText, &itemType, &theHandle, &theRect );
  545.     GetDialogItemText ( theHandle, tmpString );
  546.     StringToNum ( tmpString, &tmpNum );
  547.     (*(NumVersion*)&theItem->currVersion).minorAndBugRev += tmpNum;
  548.     
  549.     GetDialogItem ( theDialog, kCurrentStagePopup, &itemType, &theHandle, &theRect );
  550.     tmpNum = GetControlValue ( (ControlHandle) theHandle );
  551.     (*(NumVersion*)&theItem->currVersion).stage = GetStageFromItem ( tmpNum );
  552.     
  553.     GetDialogItem ( theDialog, kCurrentNonRelEditText, &itemType, &theHandle, &theRect );
  554.     GetDialogItemText ( theHandle, tmpString );
  555.     StringToNum ( tmpString, &tmpNum );
  556.     (*(NumVersion*)&theItem->currVersion).nonRelRev = tmpNum;
  557.     
  558.     // Old Version
  559.     GetDialogItem ( theDialog, kOldMajorEditText, &itemType, &theHandle, &theRect );
  560.     GetDialogItemText ( theHandle, tmpString );
  561.     StringToNum ( tmpString, &tmpNum );
  562.     (*(NumVersion*)&theItem->oldDefVersion).majorRev = tmpNum;
  563.     
  564.     GetDialogItem ( theDialog, kOldMinorEditText, &itemType, &theHandle, &theRect );
  565.     GetDialogItemText ( theHandle, tmpString );
  566.     StringToNum ( tmpString, &tmpNum );
  567.     (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev = tmpNum << 4;
  568.     
  569.     GetDialogItem ( theDialog, kOldBugRevEditText, &itemType, &theHandle, &theRect );
  570.     GetDialogItemText ( theHandle, tmpString );
  571.     StringToNum ( tmpString, &tmpNum );
  572.     (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev += tmpNum;
  573.     
  574.     GetDialogItem ( theDialog, kOldStagePopup, &itemType, &theHandle, &theRect );
  575.     tmpNum = GetControlValue ( (ControlHandle) theHandle );
  576.     (*(NumVersion*)&theItem->oldDefVersion).stage = GetStageFromItem ( tmpNum );
  577.     
  578.     GetDialogItem ( theDialog, kOldNonRelEditText, &itemType, &theHandle, &theRect );
  579.     GetDialogItemText ( theHandle, tmpString );
  580.     StringToNum ( tmpString, &tmpNum );
  581.     (*(NumVersion*)&theItem->oldDefVersion).nonRelRev = tmpNum;
  582.     
  583.     // Stack size. Only relevant if this thing's an application
  584.     GetDialogItem ( theDialog, kStackSizeEditText, &itemType, &theHandle, &theRect );
  585.     GetDialogItemText ( theHandle, tmpString );
  586.     StringToNum ( tmpString, &theItem->appStackSize );
  587.     
  588.     // Resource ID of an alias record to look for fragments. We don't do much with this.
  589.     GetDialogItem ( theDialog, kSubFolderIDEditText, &itemType, &theHandle, &theRect );
  590.     GetDialogItemText ( theHandle, tmpString );
  591.     StringToNum ( tmpString, &theItem->appStackSize );
  592.     
  593.     // Usage. Is this an application, library, or what.
  594.     GetDialogItem ( theDialog, kUsagePopup, &itemType, &theHandle, &theRect );
  595.     theItem->usage = GetControlValue ( (ControlHandle) theHandle ) - 1;
  596.     
  597.     
  598.     return noErr;
  599. }
  600.  
  601.  
  602.  
  603. void GetNameFromDialog ( DialogRef theDialog, StringPtr theName )
  604. {
  605.     int16    itemType;
  606.     Handle    theHandle;
  607.     Rect    theRect;
  608.     
  609.     // Just the name of the fragment
  610.     GetDialogItem ( theDialog, kNameEditText, &itemType, &theHandle, &theRect );
  611.     GetDialogItemText ( theHandle, theName );
  612. }
  613.  
  614.  
  615.  
  616. //
  617. // Convert between the popup item number and what it means
  618. //
  619. int8 GetStageFromItem ( int16 theItem )
  620. {
  621.     int8 theStage = 0;
  622.     
  623.     switch ( theItem )
  624.     {
  625.         case 1:
  626.             theStage = 0x20;
  627.         break;
  628.         
  629.         case 2:
  630.             theStage = 0x40;
  631.         break;
  632.         
  633.         case 3:
  634.             theStage = 0x60;
  635.         break;
  636.         
  637.         case 4:
  638.             theStage = 0x80;
  639.         break;
  640.     }
  641.     
  642.     return theStage;
  643. }
  644.  
  645.  
  646.  
  647. //
  648. // Convert between the popup item number and what it means
  649. //
  650. int16 GetItemFromStage ( int8 theStage )
  651. {
  652.     int16 theItem = 0;
  653.     
  654.     switch ( theStage )
  655.     {
  656.         case 0x20:
  657.             theItem = 1;
  658.         break;
  659.         
  660.         case 0x40:
  661.             theItem = 2;
  662.         break;
  663.         
  664.         case 0x60:
  665.             theItem = 3;
  666.         break;
  667.         
  668.         case 0x80:
  669.             theItem = 4;
  670.         break;
  671.     }
  672.     
  673.     return theItem;
  674. }
  675.  
  676.  
  677.  
  678. //
  679. // Handle a click in a dialog
  680. //
  681. void DoDialogContentClick ( DialogRef theDialog, EventRecord* theEvent )
  682. {
  683.     SInt16 itemHit;
  684.     
  685.     
  686.     SetPort ( theDialog );
  687.     
  688.     if ( DialogSelect ( theEvent, &theDialog, &itemHit ) )
  689.         DoDialogItemHit ( theDialog, itemHit );
  690.     else
  691.     {
  692.         if ( GetWindowType ( theDialog ) == kListWindowType )
  693.         {
  694.             ListRef            theList;
  695.             tDialogInfoPtr    theInfo;
  696.             Point            localPt;
  697.             
  698.             
  699.             theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  700.             theList = theInfo->listRef;
  701.             
  702.             localPt = theEvent->where;
  703.             GlobalToLocal ( &localPt );
  704.             
  705.             if ( LClick ( localPt, theEvent->modifiers, theList ) )        /* double clicked? */
  706.                 DoDialogItemHit ( theDialog, kStdOkItemIndex );
  707.         }    
  708.     }
  709.     
  710.     
  711.     return;
  712. }
  713.  
  714.  
  715.  
  716. //
  717. // Handle a dialog item hit
  718. //
  719. void DoDialogItemHit ( DialogRef theDialog, int16 theItem )
  720. {
  721.     switch ( theItem )
  722.     {
  723.         case kStdOkItemIndex:
  724.         {
  725.             int16    theSubType;
  726.             
  727.             theSubType = GetWindowSubType ( theDialog );
  728.             switch ( theSubType )
  729.             {
  730.                 case kMoveFragmentWindowSubType:
  731.                     MoveCopySelectedFragments ( theDialog, true );
  732.                 break;
  733.                 
  734.                 case kCopyFragmentWindowSubType:
  735.                     MoveCopySelectedFragments ( theDialog, false );
  736.                 break;
  737.                 
  738.                 default:
  739.                     if ( GetWindowType ( theDialog ) == kGetInfoWindowType )
  740.                     {
  741.                         tDialogInfoPtr    theInfo;
  742.                         tStreamRef        theStream;
  743.                         
  744.                         
  745.                         theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  746.                         theStream = (tStreamRef) theInfo->refCon;
  747.                         if ( theStream )
  748.                         {
  749.                             OSErr        theErr;
  750.                             int16        theIndex;
  751.                             WindowRef    theWindow;
  752.                             tItemPtr    theItem;
  753.                             Str255        theName;
  754.                             
  755.                             
  756.                             ResetStreamCursor ( theStream );
  757.                             theErr = GetStreamData ( theStream, (Ptr) &theWindow, sizeof ( WindowRef ) );
  758.                             theErr = GetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  759.                             DisposeStream ( theStream );
  760.                             
  761.                             theItem = GetNthWindowItem ( theWindow, theIndex );
  762.                             GetNameFromDialog ( theDialog, theName );
  763.                             UpdateFragInList ( theWindow, theIndex, theName );
  764.                             GetDialogValues ( theDialog, theItem );
  765.                             
  766.                             SetDocumentDirty ( theWindow, true );
  767.                         }
  768.                     }
  769.                 break;
  770.             }
  771.             DestroyDialog ( theDialog );
  772.         }
  773.         break;
  774.         
  775.         case kStdCancelItemIndex:
  776.             DestroyDialog ( theDialog );
  777.         break;
  778.     }
  779.     return;
  780.     
  781. } // DoDialogItemHit
  782.  
  783.  
  784.  
  785. //
  786. // Perform's the copy/move after the user selects a traget document
  787. // from the dialog.
  788. //
  789. void MoveCopySelectedFragments ( DialogRef theDialog, Boolean bMove )
  790. {
  791.     int16            theIndex = 0;
  792.     tDialogInfoPtr    theInfo;
  793.     
  794.     
  795.     theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  796.     if ( GetSelection ( theInfo->listRef, &theIndex ) )
  797.     {
  798.         OSErr            theErr;
  799.         int                theCount, i;
  800.         WindowRef        sourceWindow, targetWindow;
  801.         tStreamRef        theStream;
  802.         
  803.         
  804.         
  805.         // All the information is passed in a data stream
  806.         // built by the PackageWindowData routine. It consists of the source
  807.         // window reference, the number of fragments to copy or move, and
  808.         // then an array of index values.
  809.         
  810.         targetWindow = GetIndexedDocumentWindow ( theIndex );
  811.         if ( targetWindow == nil )
  812.         {
  813.             AlertUser ( kGenericErrorStr, 0, nil );
  814.             return;
  815.         }
  816.         
  817.         theStream = (tStreamRef) theInfo->refCon;
  818.         ResetStreamCursor ( theStream );
  819.         theErr = GetStreamData ( theStream, (Ptr) &sourceWindow, sizeof ( WindowRef ) );
  820.         theErr = GetStreamData ( theStream, (Ptr) &theCount, sizeof ( int ) );
  821.         
  822.         for ( i = 0; i < theCount; i++ )
  823.         {
  824.             theErr = GetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  825.             if ( bMove )
  826.                 theErr = MoveWindowFragment ( sourceWindow, theIndex, targetWindow );
  827.             else
  828.                 theErr = CopyWindowFragment ( sourceWindow, theIndex, targetWindow );
  829.         }
  830.         
  831.         DisposeStream ( theStream );
  832.         
  833.     }
  834.     
  835.     return;
  836. }
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.